{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Folium TimestampedGeoJson Demo\n",
    "\n",
    "<img align=\"right\" src=\"https://anitagraser.github.io/movingpandas/assets/img/movingpandas.png\">\n",
    "\n",
    "This notebook demonstrates how to combine MovingPandas and the **Folium [TimestampedGeoJson](https://python-visualization.github.io/folium/plugins.html#folium.plugins.TimestampedGeoJson)** plugin to create an animated trajectory visualization. \n",
    "\n",
    "*This approach was proposed by [David Bailey](https://github.com/anitagraser/movingpandas/issues/103)*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import urllib\n",
    "import os\n",
    "import pandas as pd\n",
    "import geopandas as gpd\n",
    "from geopandas import GeoDataFrame, read_file\n",
    "from shapely.geometry import Point, LineString, Polygon\n",
    "from pyproj import CRS\n",
    "from datetime import datetime, timedelta\n",
    "from matplotlib import pyplot as plt\n",
    "import movingpandas as mpd\n",
    "import folium\n",
    "from folium.plugins import TimestampedGeoJson\n",
    "import random\n",
    "\n",
    "import warnings\n",
    "warnings.simplefilter(\"ignore\")\n",
    "\n",
    "import panel as pn\n",
    "import panel.widgets as pnw"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = read_file('../data/geolife_small.gpkg')\n",
    "df['t'] = pd.to_datetime(df['t'])\n",
    "df = df.set_index('t').tz_localize(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "trajs = mpd.TrajectoryCollection(df, 'trajectory_id')\n",
    "trajs = mpd.MinTimeDeltaGeneralizer(trajs).generalize(tolerance=timedelta(minutes=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_traj = trajs.trajectories[1]\n",
    "my_traj.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def traj_to_timestamped_geojson(trajectory):\n",
    "    features = []\n",
    "    df = trajectory.df.copy()\n",
    "    df[\"previous_geometry\"] = df[\"geometry\"].shift()\n",
    "    df[\"time\"] = df.index\n",
    "    df[\"previous_time\"] = df[\"time\"].shift()\n",
    "    for _, row in df.iloc[1:].iterrows():\n",
    "        coordinates = [\n",
    "            [\n",
    "                row[\"previous_geometry\"].xy[0][0],\n",
    "                row[\"previous_geometry\"].xy[1][0]\n",
    "            ],\n",
    "            [\n",
    "                row[\"geometry\"].xy[0][0],\n",
    "                row[\"geometry\"].xy[1][0]\n",
    "            ]\n",
    "        ]\n",
    "        times = [row[\"previous_time\"].isoformat(), row[\"time\"].isoformat()]\n",
    "        features.append(\n",
    "            {\n",
    "                \"type\": \"Feature\",\n",
    "                \"geometry\": {\n",
    "                    \"type\": \"LineString\",\n",
    "                    \"coordinates\": coordinates,\n",
    "                },\n",
    "                \"properties\": {\n",
    "                    \"times\": times,\n",
    "                    \"style\": {\n",
    "                        \"color\": '#2196f3',\n",
    "                        \"weight\": 5,\n",
    "                    },\n",
    "                },\n",
    "            }\n",
    "        )\n",
    "    return features\n",
    "\n",
    "\n",
    "features = traj_to_timestamped_geojson(my_traj)\n",
    "xy = my_traj.get_start_location()\n",
    "m = folium.Map(location=[xy.y, xy.x], zoom_start=14)\n",
    "\n",
    "TimestampedGeoJson(\n",
    "    {\n",
    "        \"type\": \"FeatureCollection\",\n",
    "        \"features\": features,\n",
    "    },\n",
    "    period=\"PT1S\",\n",
    "    add_last_point=True,\n",
    "    transition_time=10\n",
    ").add_to(m)\n",
    "\n",
    "m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
